use reqwest::Client;
use serde::{Deserialize, Serialize};

use crate::common::Response;

#[derive(Clone, Debug, Serialize)]
pub struct PhoneNumberReq {
    code: String,
    openid: Option<String>,
}

impl PhoneNumberReq {
    pub fn new<T>(code: T) -> Self
    where
        T: AsRef<str>,
    {
        Self {
            code: code.as_ref().to_owned(),
            openid: None,
        }
    }

    pub fn new_with_openid<T>(code: T, openid: T) -> Self
    where
        T: AsRef<str>,
    {
        Self {
            code: code.as_ref().to_owned(),
            openid: Some(openid.as_ref().to_owned()),
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct PhoneNumberRes {
    pub phone_info: PhoneInfo,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PhoneInfo {
    pub phone_number: String,
    pub pure_phone_number: String,
    pub country_code: String,
    pub watermark: WaterMark,
}

#[derive(Clone, Debug, Deserialize)]
pub struct WaterMark {
    pub timestamp: u32,
    pub appid: String,
}

pub async fn get_phone_number<T>(
    token: T,
    req: &PhoneNumberReq,
) -> Result<Response<PhoneNumberRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = format!(
        "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={}",
        token.as_ref()
    );
    let client = Client::new();
    client
        .post(url)
        .json(req)
        .send()
        .await?
        .json::<Response<PhoneNumberRes>>()
        .await
}
